package thread;

import io.vertx.core.json.JsonObject;

import java.io.*;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.channels.FileChannel;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * NioSocketThread
 *
 * @author liyixin
 * @date 2019/1/23
 */
public class NioSocketThread extends Thread {

    private int port;

    private String ip;

    public NioSocketThread(String ip, int port) {
        this.port = port;
        this.ip = ip;
    }

    @Override
    public void run() {
        try {
            ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
            serverSocketChannel.configureBlocking(true);

            ServerSocket serverSocket = serverSocketChannel.socket();
            serverSocket.bind(new InetSocketAddress(ip, port));

            ExecutorService SERVICE = new ThreadPoolExecutor(20, Integer.MAX_VALUE,
                    60L, TimeUnit.SECONDS,
                    new SynchronousQueue<Runnable>());

            System.out.println("NIO Server Start :" + ip + " : " + port);
            while (true) {
                SocketChannel socketChannel = serverSocketChannel.accept();
                socketChannel.configureBlocking(true);
                Socket socket = socketChannel.socket();
                SERVICE.execute(() -> {
                    try {
                        //System.out.println("Connect :" + Thread.currentThread().getName());
                        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));

                        JsonObject msg = new JsonObject(br.readLine());
                        int size = Integer.parseInt(msg.getJsonObject("dataMap").getString("obj_size"));
                        bw.write("ok*");
                        bw.flush();

                        RandomAccessFile file = new RandomAccessFile("/fs-SP2-1/test/test", "rw");
                        FileChannel fileChannel = file.getChannel();

                        long startTime = System.currentTimeMillis();
                        long count = fileChannel.transferFrom(socketChannel, 0, 1024 + size);
                        long endTime = System.currentTimeMillis();
                        //System.out.println("time :" + (endTime - startTime));

                        bw.write("B89117B0DD1FDC9863202A8E25FDFC83*");
                        bw.flush();
                        socketChannel.close();
                        socket.close();
                        file.close();
                        fileChannel.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                });
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
